package com.yang.utils;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author 张恒阳
 *生产消费示例
 */
public class ObjectBuffer {
	//同步锁对象
	private static final Lock lock = new ReentrantLock();
	//生产者监视器
	private static final Condition notFull = lock.newCondition();
	//消费者监视器
	private static final Condition notEmpty = lock.newCondition();
	//缓存容器
	private static final Object[] items = new Object[100];
	private static final StringBuilder sb = new StringBuilder("true");
	// 生产者统计次数
	private static int putptr;
	// 消费者统计次数
	private static int takeptr;
	// 资源统计次数
	private static int count;

	/**
	 * 设置装箱地
	 * 
	 * @param cus
	 * @throws InterruptedException
	 */
	public static void put(Object Object) throws InterruptedException {
		lock.lock();
		try {
			while (count == items.length) {
				notFull.await();
			}
			items[putptr] = Object;
			if (++putptr == items.length){
				putptr = 0;
			}
			++count;
			notEmpty.signal();
		} finally {
			lock.unlock();
		}

	}

	/**
	 * 获取一共Object对象
	 * 
	 * @return
	 * @throws InterruptedException
	 */
	public static Object take() throws InterruptedException {
		lock.lock();

		try {
			while (count == 0) {
				notEmpty.await();
			}

			Object x = items[takeptr];
			if (++takeptr == items.length) {
				takeptr = 0;
			}
			--count;
			notFull.signal();
			return x;
		} finally {
			lock.unlock();
		}
	}

	// 获取一个随机装箱地
	public static Object takeByBuff() throws InterruptedException {
		lock.lock();
		final Thread th = Thread.currentThread();

		try {
			while (count == 0) {
				// 加入一个线程
				if (new Boolean(sb.toString())) {
					newThreadPut(100, th);
				}
				// joinThreadPut(1);
				notEmpty.await();
			}

			Object x = items[takeptr];
			if (x == null) {

			}

			if (++takeptr == items.length)
				takeptr = 0;
			--count;
			notFull.signal();
			return x;
		} finally {
			lock.unlock();
		}
	}

	/**
	 * 临时加入一共线程
	 * 
	 * @param count
	 * @throws InterruptedException
	 */
	private static void joinThreadPut(final Integer count) throws InterruptedException {
		Thread thread = new Thread(new Runnable() {
			public void run() {
				try {
					lock.lock();
					Object cu = null;
					for (int i = 0; i < count; i++) {
						cu = new Object();
						ObjectBuffer.put(cu);
					}
				} catch (InterruptedException e) {

				} finally {
					lock.unlock();
				}
			}
		});
		// 放大优先级
		thread.setPriority(Thread.MAX_PRIORITY);
		thread.start();
		// 先生产一个 无需等待
		thread.join();
	}

	private static void newThreadPut(final Integer sum, final Thread th) {
		final Thread thread = new Thread(new Runnable() {
			public void run() {
				// 开始线程
				lock.lock();
				sb.delete(0, sb.length());
				// 置换标识
				sb.append("false");
				try {
					// 创建一个资源
					System.out.println("开启一个线程");
					for (int i = 0; i < sum; i++) {
						ObjectBuffer.put(ObjectBuffer.getObject());
					}
				} catch (InterruptedException e) {
					th.interrupt();
				} finally {
					sb.delete(0, sb.length());
					sb.append("true");
					lock.unlock();
				}
				// notEmpty.signal();
			}
		});
		thread.setPriority(Thread.MIN_PRIORITY);
		thread.start();
	}

	public static void main(String[] args) throws InterruptedException {
		for (int i = 0; i < 100000; i++) {
			ObjectBuffer.takeByBuff();
		}
	}

	/**
	 * 根据条件获取对应的cu
	 * 
	 * @return
	 */
	private static Object getObject() {
		Object cu = new Object();

		return cu;

	}

}
